package com.zck.thumbup.job;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.StrPool;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zck.thumbup.entity.Thumb;
import com.zck.thumbup.mapper.BlogMapper;
import com.zck.thumbup.model.enums.ThumbTypeEnum;
import com.zck.thumbup.service.ThumbService;
import com.zck.thumbup.util.RedisKeyUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * 定时把Redis中临时点赞数据同步到数据库
 * @author 赵承康
 * @date 2025/10/24
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class SyncThumb2DBJob {
    private final ThumbService thumbService;
    private final BlogMapper blogMapper;
    private final RedisTemplate<String,Object> redisTemplate;

    @Scheduled(fixedDelay = 10000)
    @Transactional(rollbackFor = Exception.class)
    public void run(){
        log.info("开始执行");
        DateTime nowDate = DateUtil.date();
        //如果秒数为0-9,则回到上一分钟的50秒
        int second = (DateUtil.second(nowDate) / 10 - 1) * 10;
        if (second==-10) {
            second=50;
            nowDate=DateUtil.offsetMinute(nowDate,-1);
        }

        String data = DateUtil.format(nowDate, "HH:mm:") + second;
        syncThumb2DBByDate(data);
    }

    public void syncThumb2DBByDate(String date){
        //获取临时点赞和取消点赞数据
        String tempThumbKey = RedisKeyUtil.getTempThumbKey(date);
        Map<Object, Object> allTempThumbMap = redisTemplate.opsForHash().entries(tempThumbKey);

        boolean thumbMapEmpty = CollUtil.isEmpty(allTempThumbMap);

        //同步点赞到数据库
        //构建插入列表并收集blogId
        Map<Long, Long> blogThumbCountMap = new HashMap<>();
        if (thumbMapEmpty) {
            return;
        }
        ArrayList<Thumb> thumbList = new ArrayList<>();
        LambdaQueryWrapper<Thumb> wrapper = new LambdaQueryWrapper<>();
        boolean needRemove=false;

        for (Object userIdBlogIdObj : allTempThumbMap.keySet()) {
            String userIdBlogId = (String) userIdBlogIdObj;
            String[] userIdAndBlogId = userIdBlogId.split(StrPool.COLON);
            Long userId = Long.valueOf(userIdAndBlogId[0]);
            Long blogId = Long.valueOf(userIdAndBlogId[1]);

            //-1取消点赞,1点赞
            Integer thumbType = Integer.valueOf(allTempThumbMap.get(userIdBlogId).toString());
            if (thumbType== ThumbTypeEnum.INCR.getValue()) {
                Thumb thumb = new Thumb();
                thumb.setUserId(userId);
                thumb.setBlogId(blogId);
                thumbList.add(thumb);
            }else if(thumbType==ThumbTypeEnum.DECR.getValue()){
                //拼接查询条件，批量删除
                needRemove=true;
                wrapper.or().eq(Thumb::getUserId,userId).eq(Thumb::getBlogId,blogId);
            }else{
                if (thumbType!= ThumbTypeEnum.NON.getValue()) {
                    log.warn("数据异常: {}",userId+","+blogId+","+thumbType);
                }
                continue;
            }
            //计算点赞增量
            blogThumbCountMap.put(blogId,blogThumbCountMap.getOrDefault(blogId,0L)+thumbType);
        }

        //批量插入
        thumbService.saveBatch(thumbList);
        //批量删除
        if (needRemove) {
            thumbService.remove(wrapper);
        }
        //批量更新博客点赞量
        if (!blogThumbCountMap.isEmpty()) {
            blogMapper.batchUpdateThumbCount(blogThumbCountMap);
        }
        //异步删除
        Thread.startVirtualThread(()->{
            redisTemplate.delete(tempThumbKey);
        });
    }

}
